package experiment3.shudu001.models;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;

import java.util.HashSet;
import java.util.Set;

import experiment3.shudu001.activity.CompletionActivity;
import experiment3.shudu001.activity.GameActivity;
import experiment3.shudu001.views.SudokuBoard;

/**
 * Created by HP on 2025/4/26.
 * 数独游戏核心引擎类
 * 处理游戏逻辑，包括生成数独、处理用户输入、冲突检测、保存/加载游戏状态等
 *
 */

public class GameEngine {

    private static final String PREFS_NAME = "SudokuPrefs";
    private static final String GAME_STATE_KEY = "gameState";
    private static final String ELAPSED_TIME_KEY = "elapsedTime";
    private static final String DIFFICULTY_KEY = "difficulty";

    private int[][] board;
    private boolean[][] fixedCells;
    private boolean[][][] notes;
    private int selectedRow = -1;
    private int selectedCol = -1;
    private int mistakes = 0;
    private boolean notesMode = false;
    private boolean gameCompleted = false;
    private int difficulty;
    private long elapsedTime = 0;
    private SudokuBoard sudokuBoard;
    private Context context;
    private SudokuGenerator generator;
    private SudokuSolver solver;

    public GameEngine(Context context, int difficulty, boolean loadSaved) {
        this.context = context;
        this.difficulty = difficulty;
        this.generator = new SudokuGenerator(); // 确保 SudokuGenerator 类已正确实现
        this.solver = new SudokuSolver(); // 确保 SudokuSolver 类已正确实现

        if (loadSaved) {
            loadGame();
        } else {
            newGame();
        }
    }

    /**
     * 初始化新游戏
     * 生成新数独棋盘并初始化相关状态
     */
    private void newGame() {
        board = generator.generate(difficulty);
        fixedCells = new boolean[9][9];
        notes = new boolean[9][9][9];

        // 标记固定单元格
        for (int row = 0; row < 9; row++) {
            for (int col = 0; col < 9; col++) {
                if (board[row][col] != 0) {
                    fixedCells[row][col] = true;
                }
            }
        }

        mistakes = 0;
        gameCompleted = false;
        selectedRow = -1;
        selectedCol = -1;
        notesMode = false;
        elapsedTime = 0;
    }

    /**
     * 设置当前选中的单元格
     * @param row 行号（0-8）
     * @param col 列号（0-8）
     */
    public void setSelectedCell(int row, int col) {
        if (!fixedCells[row][col]) {
            selectedRow = row;
            selectedCol = col;
            if (sudokuBoard != null) {
                sudokuBoard.updateSelectedCell(row, col);
            }
        }
    }

    /**
     * 处理数字输入（根据当前模式设置数值或笔记）
     * @param number 输入的数字（1-9）
     */
    public void setSelectedNumber(int number) {
        if (selectedRow != -1 && selectedCol != -1 && !fixedCells[selectedRow][selectedCol]) {
            if (notesMode) {
                toggleNote(number);  // 笔记模式：切换笔记
            } else {
                setCellValue(number); // 普通模式：设置单元格值
            }
        }
    }

    /**
     * 设置单元格数值并检查冲突
     * @param number 要设置的数字（1-9）
     */
    private void setCellValue(int number) {
        if (number >= 1 && number <= 9) {
            board[selectedRow][selectedCol] = number;

            // 检查冲突
            if (isConflictingCellInternal(selectedRow, selectedCol)) {
                mistakes++;
                // 更新错误显示
                if (context instanceof GameActivity) {
                    ((GameActivity) context).updateMistakes();
                }
                // 错误达到5次时处理
                if (mistakes >= 5) {
                    if (context instanceof GameActivity) {
                        ((GameActivity) context).onGameFailed();
                    }
                    return; // 重要！防止继续执行
                }
                if (context instanceof GameActivity){
                    ((GameActivity) context).showErrorToast();
                }
            }
            checkCompletion();
            if (sudokuBoard != null) {
                sudokuBoard.invalidate();
            }
        }
    }

    private void toggleNote(int number) {
        if (number >= 1 && number <= 9) {
            notes[selectedRow][selectedCol][number - 1] = !notes[selectedRow][selectedCol][number - 1];
            if (sudokuBoard != null) {
                sudokuBoard.invalidate();
            }
        }
    }

    public void eraseCell() {
        if (selectedRow != -1 && selectedCol != -1 && !fixedCells[selectedRow][selectedCol]) {
            board[selectedRow][selectedCol] = 0;
            notes[selectedRow][selectedCol] = new boolean[9];
            if (sudokuBoard != null) {
                sudokuBoard.invalidate();
            }
        }
    }

    //提示功能,使用数独求解器提供提示
    public void giveHint() {
        if (selectedRow != -1 && selectedCol != -1 && !fixedCells[selectedRow][selectedCol]) {
            int[][] solution = solver.solve(board);
            if (solution != null) {
                board[selectedRow][selectedCol] = solution[selectedRow][selectedCol];
                checkCompletion();
                if (sudokuBoard != null) {
                    sudokuBoard.invalidate();
                }
            }
        }
    }

    public void toggleNotesMode() {
        notesMode = !notesMode;
    }

    private boolean isConflictingCellInternal(int row, int col) {
        if (board[row][col] == 0) return false;

        // 检查行冲突
        for (int c = 0; c < 9; c++) {
            if (c != col && board[row][c] == board[row][col]) {
                return true;
            }
        }

        // 检查列冲突
        for (int r = 0; r < 9; r++) {
            if (r != row && board[r][col] == board[row][col]) {
                return true;
            }
        }

        // 检查3x3宫格冲突
        int boxStartRow = row / 3 * 3;
        int boxStartCol = col / 3 * 3;
        for (int r = boxStartRow; r < boxStartRow + 3; r++) {
            for (int c = boxStartCol; c < boxStartCol + 3; c++) {
                if (r != row && c != col && board[r][c] == board[row][col]) {
                    return true;
                }
            }
        }

        return false;
    }

    public boolean isConflictingCell(int row, int col) {
        return board[row][col] != 0 && isConflictingCellInternal(row, col);
    }

    /**
     * 检查游戏是否完成（所有单元格正确填充且无冲突）
     */
    private void checkCompletion() {
        boolean isComplete = true;
        for (int row = 0; row < 9; row++) {
            for (int col = 0; col < 9; col++) {
                if (board[row][col] == 0 || isConflictingCellInternal(row, col)) {
                    isComplete = false;
                    break;
                }
            }
            if (!isComplete) break;
        }
        if (isComplete) {
            gameCompleted = true;
            if (context instanceof GameActivity) {
                ((GameActivity) context).onGameCompleted();
            }
        }
    }


    /**
     * 保存游戏状态到SharedPreferences
     * @param elapsedTime 当前已用时间（用于保存）
     */
    public void saveGame(long elapsedTime) {
        if (gameCompleted) return;

        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();

        // 保存棋盘状态
        Set<String> boardSet = new HashSet<>();
        for (int row = 0; row < 9; row++) {
            for (int col = 0; col < 9; col++) {
                boardSet.add(row + "," + col + "," + board[row][col]);
            }
        }
        editor.putStringSet("board", boardSet);

        // 保存固定单元格
        Set<String> fixedSet = new HashSet<>();
        for (int row = 0; row < 9; row++) {
            for (int col = 0; col < 9; col++) {
                if (fixedCells[row][col]) {
                    fixedSet.add(row + "," + col);
                }
            }
        }
        editor.putStringSet("fixedCells", fixedSet);

        // 保存笔记
        Set<String> notesSet = new HashSet<>();
        for (int row = 0; row < 9; row++) {
            for (int col = 0; col < 9; col++) {
                if (notes[row][col] != null) {
                    for (int note = 0; note < 9; note++) {
                        if (notes[row][col][note]) {
                            notesSet.add(row + "," + col + "," + note);
                        }
                    }
                }
            }
        }
        editor.putStringSet("notes", notesSet);

        // 保存其他状态
        editor.putInt("mistakes", mistakes);
        editor.putBoolean("notesMode", notesMode);
        editor.putLong("elapsedTime", elapsedTime);
        editor.putInt("difficulty", difficulty);

        editor.apply();
    }

    private void loadGame() {
        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);

        // 加载棋盘
        board = new int[9][9];
        Set<String> boardSet = prefs.getStringSet("board", null);
        if (boardSet != null) {
            boardSet = new HashSet<>(boardSet);
        } else {
            boardSet = new HashSet<>();
        }
        for (String cell : boardSet) {
            String[] parts = cell.split(",");
            int row = Integer.parseInt(parts[0]);
            int col = Integer.parseInt(parts[1]);
            int value = Integer.parseInt(parts[2]);
            board[row][col] = value;
        }

        // 加载固定单元格
        fixedCells = new boolean[9][9];
        Set<String> fixedSet = prefs.getStringSet("fixedCells", null);
        if (fixedSet != null) {
            fixedSet = new HashSet<>(fixedSet);
        } else {
            fixedSet = new HashSet<>();
        }
        for (String cell : fixedSet) {
            String[] parts = cell.split(",");
            int row = Integer.parseInt(parts[0]);
            int col = Integer.parseInt(parts[1]);
            fixedCells[row][col] = true;
        }

        // 加载笔记
        notes = new boolean[9][9][9];
        Set<String> notesSet = prefs.getStringSet("notes", null);
        if (notesSet != null) {
            notesSet = new HashSet<>(notesSet);
        } else {
            notesSet = new HashSet<>();
        }
        for (String note : notesSet) {
            String[] parts = note.split(",");
            int row = Integer.parseInt(parts[0]);
            int col = Integer.parseInt(parts[1]);
            int noteNum = Integer.parseInt(parts[2]);
            notes[row][col][noteNum] = true;
        }

        // 加载其他状态
        mistakes = prefs.getInt("mistakes", 0);
        notesMode = prefs.getBoolean("notesMode", false);
        elapsedTime = prefs.getLong("elapsedTime", 0);
        difficulty = prefs.getInt("difficulty", 1);
    }

    // Getters
    public int getCellValue(int row, int col) { return board[row][col]; }
    public boolean isFixedCell(int row, int col) { return fixedCells[row][col]; }
    public boolean[] getNotes(int row, int col) { return notes[row][col]; }
    public boolean isCellConflicting(int row, int col) { return board[row][col] != 0 && isCellConflicting(row, col); }
    public int getMistakes() { return mistakes; }
    public boolean isNotesMode() { return notesMode; }
    public boolean isGameCompleted() { return gameCompleted; }
    public int getDifficulty() { return difficulty; }
    public long getElapsedTime() { return elapsedTime; }
    public boolean isNewGame() { return elapsedTime == 0; }

    public void setSudokuBoard(SudokuBoard sudokuBoard) {
        this.sudokuBoard = sudokuBoard;
    }
}